/*
Copyright [2020] [https://www.stylefeng.cn]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Guns采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：

1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改Guns源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处，作者声明等。
4.分发源码时候，请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名，模块名称，项目代码等时，请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点，可申请商业授权，获取Guns商业授权许可，请在官网购买授权，地址为 https://www.stylefeng.cn
 */
package cn.stylefeng.guns.sys.modular.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.core.consts.CommonConstant;
import cn.stylefeng.guns.core.consts.SymbolConstant;
import cn.stylefeng.guns.core.context.constant.ConstantContextHolder;
import cn.stylefeng.guns.core.context.login.LoginContextHolder;
import cn.stylefeng.guns.core.enums.CommonStatusEnum;
import cn.stylefeng.guns.core.enums.CoreExceptionEnum;
import cn.stylefeng.guns.core.exception.CustomException;
import cn.stylefeng.guns.core.exception.PermissionException;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.exception.enums.PermissionExceptionEnum;
import cn.stylefeng.guns.core.exception.enums.StatusExceptionEnum;
import cn.stylefeng.guns.core.factory.PageFactory;
import cn.stylefeng.guns.core.pojo.login.SysLoginUser;
import cn.stylefeng.guns.core.pojo.page.PageResult;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.core.util.PoiUtil;
import cn.stylefeng.guns.sys.core.enums.AdminTypeEnum;
import cn.stylefeng.guns.sys.core.enums.PublicEnum;
import cn.stylefeng.guns.sys.modular.constant.DictConstant;
import cn.stylefeng.guns.sys.modular.dict.entity.SysDictData;
import cn.stylefeng.guns.sys.modular.dict.mapper.SysDictDataMapper;
import cn.stylefeng.guns.sys.modular.emp.entity.SysEmp;
import cn.stylefeng.guns.sys.modular.emp.mapper.SysEmpMapper;
import cn.stylefeng.guns.sys.modular.emp.param.SysEmpParam;
import cn.stylefeng.guns.sys.modular.emp.result.SysEmpInfo;
import cn.stylefeng.guns.sys.modular.emp.service.SysEmpService;
import cn.stylefeng.guns.sys.modular.org.entity.SysOrg;
import cn.stylefeng.guns.sys.modular.org.mapper.SysOrgMapper;
import cn.stylefeng.guns.sys.modular.org.service.SysOrgService;
import cn.stylefeng.guns.sys.modular.role.RoleConstant;
import cn.stylefeng.guns.sys.modular.role.mapper.SysRoleMapper;
import cn.stylefeng.guns.sys.modular.syssite.entity.SysSiteAdmin;
import cn.stylefeng.guns.sys.modular.syssite.service.SysSiteAdminService;
import cn.stylefeng.guns.sys.modular.user.controller.vo.ChangeOrgVo;
import cn.stylefeng.guns.sys.modular.user.controller.vo.SiteResult;
import cn.stylefeng.guns.sys.modular.user.entity.SysUser;
import cn.stylefeng.guns.sys.modular.user.entity.SysUserRole;
import cn.stylefeng.guns.sys.modular.user.enums.SysUserExceptionEnum;
import cn.stylefeng.guns.sys.modular.user.factory.MD5Ry;
import cn.stylefeng.guns.sys.modular.user.factory.SysUserFactory;
import cn.stylefeng.guns.sys.modular.user.mapper.SysUserMapper;
import cn.stylefeng.guns.sys.modular.user.param.SysUserParam;
import cn.stylefeng.guns.sys.modular.user.result.SysUserResp;
import cn.stylefeng.guns.sys.modular.user.result.SysUserResult;
import cn.stylefeng.guns.sys.modular.user.service.SysUserDataScopeService;
import cn.stylefeng.guns.sys.modular.user.service.SysUserRoleService;
import cn.stylefeng.guns.sys.modular.user.service.SysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 系统用户service接口实现类
 *
 * @author xuyuxiang
 * @date 2020/3/11 17:49
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysEmpService sysEmpService;

    @Resource
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysSiteAdminService sysSiteAdminService;

    @Resource
    private SysUserDataScopeService sysUserDataScopeService;


    @Override
    public SysUser getUserByAccount(String account, Long tenantId, String type) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getAccount, account);
        queryWrapper.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode());

        if (type != null && !"".equals(type)) {
            //用户
            if (type.equals("1")) {
                queryWrapper.eq(SysUser::getTenantId, -1);
            } else {
                queryWrapper.ne(SysUser::getTenantId, -1);
            }
        }
      /*  if (tenantId != null) {
            queryWrapper.eq(SysUser::getTenantId, tenantId);
        } else {
            queryWrapper.eq(SysUser::getTenantId,1l);
        }

       List<SysUser> list = list(queryWrapper);
        if (list.size() > 1) {
            throw new CustomException("请选择公司");
        }*/
        return this.getOne(queryWrapper);
    }

    @Override
    public SysUser getUserByName(String name) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getName, name);
        queryWrapper.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode());
        return this.getOne(queryWrapper);
    }

    @Override
    public PageResult<SysUserResp> page(SysUserParam sysUserParam) {
        QueryWrapper<SysUserResult> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(sysUserParam)) {
            //根据关键字模糊查询（姓名，账号，手机号）
            if (ObjectUtil.isNotEmpty(sysUserParam.getSearchValue())) {
                queryWrapper.and(q -> q.like("sys_user.account", sysUserParam.getSearchValue())
                        .or().like("sys_user.name", sysUserParam.getSearchValue())
                        .or().like("sys_user.phone", sysUserParam.getSearchValue()));
            }
            //根据员工所属机构查询
            if (ObjectUtil.isNotEmpty(sysUserParam.getSysEmpParam())) {
                SysEmpParam sysEmpParam = sysUserParam.getSysEmpParam();
                if (ObjectUtil.isNotEmpty(sysEmpParam.getOrgId())) {
                    //查询属于该机构的，或该机构下级所有的人员
                    queryWrapper.and(q -> q.eq("sys_emp.org_id", sysEmpParam.getOrgId())
                            .or().like("sys_org.pids", sysEmpParam.getOrgId()));
                }
            }
            //根据状态查询（0正常 1停用），删除的不会展示在列表
            if (ObjectUtil.isNotEmpty(sysUserParam.getSearchStatus())) {
                queryWrapper.eq("sys_user.status", sysUserParam.getSearchStatus());
            }
        }

        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        //租户只能查自己添加的用户,平台只能查询总平台用户
        if (sysLoginUser.getTenantId() != 1l) {
            queryWrapper.eq("sys_user.tenant_id", sysLoginUser.getTenantId());
        } else {
            queryWrapper.eq("sys_user.tenant_id", 1);
        }

        //查询非删除状态，排除超级管理员
        queryWrapper.ne("sys_user.status", CommonStatusEnum.DELETED.getCode())
                .ne("sys_user.admin_type", AdminTypeEnum.SUPER_ADMIN.getCode());
        Page<SysUserResult> page = this.baseMapper.page(PageFactory.defaultPage(), queryWrapper);
        List<SysUserResult> records = page.getRecords();
        for (SysUserResult sysUserResult : records) {
            SiteResult siteResult = this.baseMapper.getSiteName(sysUserResult.getId());
            if (siteResult != null) {
                sysUserResult.setSiteName(siteResult.getName());
                sysUserResult.setSiteId(siteResult.getId());
            }

        }
        return new PageResult(page);
    }

    @Override
    public List<Dict> list(SysUserParam sysUserParam) {
        List<Dict> dictList = CollectionUtil.newArrayList();
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotNull(sysUserParam)) {
            //根据账号，姓名模糊查询
            if (ObjectUtil.isNotEmpty(sysUserParam.getAccount())) {
                queryWrapper.and(i -> i.like(SysUser::getAccount, sysUserParam.getAccount())
                        .or().like(SysUser::getName, sysUserParam.getAccount()));
            }
        }
        //查询正常状态，排除超级管理员
        queryWrapper.eq(SysUser::getStatus, CommonStatusEnum.ENABLE.getCode())
                .ne(SysUser::getAdminType, AdminTypeEnum.SUPER_ADMIN.getCode());
        this.list(queryWrapper).forEach(sysUser -> {
            Dict dict = Dict.create();
            dict.put("id", sysUser.getId().toString());
            dict.put("firstName", sysUser.getName() + SymbolConstant.LEFT_SQUARE_BRACKETS
                    + sysUser.getAccount() + SymbolConstant.RIGHT_SQUARE_BRACKETS);
            dictList.add(dict);
        });
        return dictList;
    }

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;


    @Override
    public void add(SysUserParam sysUserParam) {
        boolean superAdmin = LoginContextHolder.me().isSuperAdmin();
        //如果登录用户不是超级管理员，则进行数据权限校验
        if (!superAdmin && !LoginContextHolder.me().isTenantAdmin()) {
            List<Long> dataScope = sysUserParam.getDataScope();
            //获取添加的用户的所属机构
            Long orgId = sysUserParam.getSysEmpParam().getOrgId();
            //数据范围为空
            if (ObjectUtil.isEmpty(dataScope)) {
                throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
            } else if (!dataScope.contains(orgId)) {
                //所添加的用户的所属机构不在自己的数据范围内
                throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
            }
        }

        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        LambdaQueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().lambda().
                eq(SysUser::getAccount, sysUserParam.getAccount()).ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode());
        if (sysLoginUser.getTenantId() != 1l) {
            queryWrapper.eq(SysUser::getTenantId, sysLoginUser.getTenantId());
        } else {
            queryWrapper.eq(SysUser::getTenantId, 1l);
        }
        //判断账号是否重复
        Integer count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new PermissionException(PermissionExceptionEnum.ACCOUNT_REPEAT);
        }
        SysUser sysUser = new SysUser();
        BeanUtil.copyProperties(sysUserParam, sysUser);
        //创建人
        //如果没有指定密码设置默认密码为234567
        String password = sysUserParam.getPassword();
        if (StringUtils.isBlank(password)) {
            sysUser.setPassword(MD5Ry.md5("234567"));
        } else {
            sysUser.setPassword(MD5Ry.md5(password));
        }
        SysUserFactory.fillAddCommonUserInfo(sysUser);
        Long tenantId = null;
        if (LoginContextHolder.me().isSuperAdmin()) {
            tenantId = 1l;
            sysUser.setTenantId(1l);
        } else {
            tenantId = sysLoginUser.getTenantId();
            sysUser.setTenantId(sysLoginUser.getTenantId());
        }

        this.save(sysUser);


        Long sysUserId = sysUser.getId();

        //增加员工信息
        SysEmpParam sysEmpParam = sysUserParam.getSysEmpParam();
        if (sysEmpParam != null) {
            sysEmpParam.setId(sysUserId);
            sysEmpService.addOrUpdate(sysEmpParam);

            List<String> empNameList = new ArrayList<>();
            empNameList.add("管理部门");
            empNameList.add("在途人员");
            empNameList.add("业务部");
            empNameList.add("财务部");

            if (empNameList.contains(sysEmpParam.getOrgName())) {
                //数据权限
                List<Long> orgId = new ArrayList<>();
                orgId.add(sysEmpParam.getOrgId());
                sysUserParam.setGrantOrgIdList(orgId);
                sysUserParam.setId(sysUser.getId());
                sysUserDataScopeService.grantData(sysUserParam);

                SysUserParam roleParam = new SysUserParam();
                //绑定角色
                List<Long> grantRoleIdList = new ArrayList<>();
                SysOrg sysOrg = sysOrgService.getById(sysEmpParam.getOrgId());
                grantRoleIdList.add(sysOrg.getRoleId());
                roleParam.setId(sysUser.getId());
                roleParam.setGrantRoleIdList(grantRoleIdList);
                grantRole(roleParam);
            }
        }


        //绑定网点和网点网点提成
        if (sysUserParam.getSiteId() != null) {
            this.baseMapper.insertSiteRelation(sysUser.getId(), sysUserParam.getSiteId(), null, tenantId);
            SysSiteAdmin site = sysSiteAdminService.getById(sysUserParam.getSiteId());
            //用户绑定部门
            if (site != null && site.getOrgId() != null) {
                //如果登录用户不是超级管理员，则进行数据权限校验
                if (!superAdmin && !LoginContextHolder.me().isTenantAdmin()) {
                    List<Long> dataScope = sysUserParam.getDataScope();
                    //获取要授权数据的用户的所属机构
                    SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId());
                    Long orgId = sysEmpInfo.getOrgId();
                    //数据范围为空
                    if (ObjectUtil.isEmpty(dataScope)) {
                        throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
                    } else if (!dataScope.contains(orgId)) {
                        //所要授权数据的用户的所属机构不在自己的数据范围内
                        throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
                    }
                }
                List<Long> orgId = new ArrayList<>();
                orgId.add(site.getOrgId());
                sysUserParam.setGrantOrgIdList(orgId);
                sysUserParam.setId(sysUser.getId());
                sysUserDataScopeService.grantData(sysUserParam);

                SysOrg sysOrg = sysOrgService.getById(site.getOrgId());
                if (sysOrg != null) {
                    //增加员工部门信息
                    SysEmpParam newsysEmpParam = new SysEmpParam();
                    newsysEmpParam.setOrgId(site.getOrgId());
                    newsysEmpParam.setOrgName(sysOrg.getName());
                    newsysEmpParam.setId(sysUserId);
                    newsysEmpParam.setExtIds(new ArrayList<>());
                    sysEmpService.addOrUpdate(newsysEmpParam);
                }
                SysUserParam roleParam = new SysUserParam();
                //绑定角色
                List<Long> grantRoleIdList = new ArrayList<>();
                grantRoleIdList.add(sysOrg.getRoleId());
                roleParam.setId(sysUser.getId());
                roleParam.setGrantRoleIdList(grantRoleIdList);
                grantRole(roleParam);


            }

        }

    }


    @Override
    public void delete(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        //不能删除超级管理员
        if (AdminTypeEnum.SUPER_ADMIN.getCode().equals(sysUser.getAdminType())) {
            throw new ServiceException(SysUserExceptionEnum.USER_CAN_NOT_DELETE_ADMIN);
        }
        sysUser.setStatus(sysUserParam.getStatus());
        this.updateById(sysUser);
        Long id = sysUser.getId();
//        //删除该用户对应的用户-角色表关联信息
//        sysUserRoleService.deleteUserRoleListByUserId(id);
    }

    @Override
    public void edit(SysUserParam sysUserParam) {
        //SysUser sysUser = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().
        //        eq(SysUser::getPhone, sysUserParam.getPhone())
        //        .ne(SysUser::getId, sysUserParam.getId())
        //        .ne(SysUser::getStatus, 2));
        //if (sysUser != null) {
        //    throw new PermissionException(PermissionExceptionEnum.MOBILE_REPEAT);
        //}
        SysUser sysUser = this.getById(sysUserParam.getId());
        BeanUtil.copyProperties(sysUserParam, sysUser);
        //账号不给编辑
        sysUser.setAccount(null);
        //重置密码
        if (StrUtil.isNotBlank(sysUserParam.getPassword())) {
            sysUser.setPassword(MD5Ry.md5(sysUserParam.getPassword()));
        }
        this.updateById(sysUser);


        Long sysUserId = sysUser.getId();
        //增加员工信息
        SysEmpParam sysEmpParam = sysUserParam.getSysEmpParam();
        sysEmpParam.setId(sysUserId);
        sysEmpService.addOrUpdate(sysEmpParam);

    }


    @Autowired
    private SysOrgService sysOrgService;

    @Override
    public SysUserResult detail(SysUserParam sysUserParam) {
        SysUserResult sysUserResult = new SysUserResult();
        //获取系统用户
        SysUser sysUser = this.querySysUser(sysUserParam);
        BeanUtil.copyProperties(sysUser, sysUserResult);
        //获取对应员工信息
        SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId());
        //设置员工信息
        sysUserResult.setSysEmpInfo(sysEmpInfo);
        return sysUserResult;


    }

    @Override
    public void changeStatus(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        //不能修改超级管理员状态
        if (AdminTypeEnum.SUPER_ADMIN.getCode().equals(sysUser.getAdminType())) {
            throw new ServiceException(SysUserExceptionEnum.USER_CAN_NOT_UPDATE_ADMIN);
        }

        Long id = sysUser.getId();

        Integer status = sysUserParam.getStatus();
        //校验状态在不在枚举值里
        CommonStatusEnum.validateStatus(status);

        //更新枚举，更新只能更新未删除状态的
        LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SysUser::getId, id)
                .and(i -> i.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode()))
                .set(SysUser::getStatus, status);
        boolean update = this.update(updateWrapper);
        if (!update) {
            throw new ServiceException(StatusExceptionEnum.UPDATE_STATUS_ERROR);
        }
    }

    @Override
    public void grantRole(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        //获取当前角色code
        if (!LoginContextHolder.me().isSuperAdmin()) {
            Long userId = this.tenantAdmin();
            if (ObjectUtil.equal(userId, sysUser.getId())) {
                throw new CustomException(CoreExceptionEnum.TEANT_ADMIND_ERROR);
            }
        }

        boolean superAdmin = LoginContextHolder.me().isSuperAdmin();
        //如果登录用户不是超级管理员，则进行数据权限校验
        if (!superAdmin && !LoginContextHolder.me().isTenantAdmin()) {
            List<Long> dataScope = sysUserParam.getDataScope();
            //获取要授权角色的用户的所属机构
            SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId());
            Long orgId = sysEmpInfo.getOrgId();
            //数据范围为空
            if (ObjectUtil.isEmpty(dataScope)) {
                throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
            } else if (!dataScope.contains(orgId)) {
                //所要授权角色的用户的所属机构不在自己的数据范围内
                throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
            }
        }
        sysUserRoleService.grantRole(sysUserParam);
    }

    private Long tenantAdmin() {
        return this.baseMapper.getuserIdByRole(RoleConstant.tenant_admin, LoginContextHolder.me().getSysLoginUser().getTenantId());
    }

    @Override
    public void grantData(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        boolean superAdmin = LoginContextHolder.me().isSuperAdmin();
        //如果登录用户不是超级管理员，则进行数据权限校验
        if (!superAdmin && !LoginContextHolder.me().isTenantAdmin()) {
            List<Long> dataScope = sysUserParam.getDataScope();
            //获取要授权数据的用户的所属机构
            SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId());
            Long orgId = sysEmpInfo.getOrgId();
            //数据范围为空
            if (ObjectUtil.isEmpty(dataScope)) {
                throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
            } else if (!dataScope.contains(orgId)) {
                //所要授权数据的用户的所属机构不在自己的数据范围内
                throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
            }
        }
        sysUserDataScopeService.grantData(sysUserParam);
    }

    @Override
    public void updateInfo(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        BeanUtil.copyProperties(sysUserParam, sysUser);
        this.updateById(sysUser);
    }

    @Override
    public void updatePwd(String oldPwd, String newPwd) {
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        SysUser sysUser = baseMapper.selectById(sysLoginUserId);
//        //新密码与原密码相同
//        if (newPwd.equals(oldPwd)) {
//            throw new ServiceException(SysUserExceptionEnum.USER_PWD_REPEAT);
//        }
//        //原密码错误
//        if (!MD5Ry.checkPwd(oldPwd, sysUser.getPassword())) {
//            throw new ServiceException(SysUserExceptionEnum.USER_PWD_ERROR);
//        }
        sysUser.setPassword(MD5Ry.md5(newPwd));
        this.updateById(sysUser);
    }
    @Override
    public void updateOtherPwd(String oldPwd, String newPwd, Long userId) {
        SysUser sysUser = baseMapper.selectById(userId);
//        //新密码与原密码相同
//        if (newPwd.equals(oldPwd)) {
//            throw new ServiceException(SysUserExceptionEnum.USER_PWD_REPEAT);
//        }
//        //原密码错误
//        if (!MD5Ry.checkPwd(oldPwd, sysUser.getPassword())) {
//            throw new ServiceException(SysUserExceptionEnum.USER_PWD_ERROR);
//        }
        sysUser.setPassword(MD5Ry.md5(newPwd));
        this.updateById(sysUser);
    }

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 验证码验证
     *
     * @param code
     * @param type
     * @return
     */
    public ResponseData checkCode(String code, Integer type, String mobile) {
        String s = redisTemplate.opsForValue().get(mobile + type + code);
        if (StrUtil.isBlank(s)) {
            return ResponseData.error("验证码错误");
        }
        String[] split = s.split(",");
        Long time = System.currentTimeMillis() - Long.valueOf(split[0].trim());
        if (time > 10 * 60 * 1000) {
            return ResponseData.error("验证码超时");
        }
        if (!split[1].trim().equals(type.toString())) {
            return ResponseData.error("操作冲突");
        }
        if (!split[2].trim().equals(code)) {
            return ResponseData.error("验证码错误");
        }
        if (!split[3].trim().equals(mobile)) {
            return ResponseData.error("手机号错误");
        }
        return ResponseData.success();
    }

    @Override
    public ResponseData forgetPwd(String pwd, String code, String mobile) {
        SysUser sysUser = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getPhone, mobile).ne(SysUser::getStatus, 2));
        if (sysUser == null) {
            return ResponseData.error(CoreExceptionEnum.ACCOUNT_NOT_EXIST);
        } else if (sysUser.getStatus().equals(1)) {
            return ResponseData.error(CoreExceptionEnum.ACCOUNT_DISABLE);
        }
        ResponseData responseData = checkCode(code, 7, mobile);
        if (!responseData.getSuccess()) {
            return responseData;
        }
        sysUser.setPassword(MD5Ry.md5(pwd));
        this.updateById(sysUser);
        return ResponseData.success();
    }


    @Override
    public ResponseData updateDefaultPwd(String pwd) {
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        SysUser sysUser = baseMapper.selectById(sysLoginUserId);
        //判断新密码是否和默认密码相同
        SysDictData sysDictData = sysDictDataMapper.selectOne(new QueryWrapper<SysDictData>().lambda().
                eq(SysDictData::getCode, DictConstant.DEFAULT_PWD).eq(SysDictData::getStatus, ""));
        String defaulfPwd = sysDictData == null || StrUtil.isBlank(sysDictData.getValue()) ? ConstantContextHolder.getDefaultPassWord() : sysDictData.getValue();
        if (defaulfPwd.equals(pwd)) {
            throw new ServiceException(SysUserExceptionEnum.NOT_USE_DEFAULT_PWD);
        }
        sysUser.setPassword(MD5Ry.md5(pwd));
        this.updateById(sysUser);
        return ResponseData.success();
    }

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysOrgMapper sysOrgMapper;


    @Override
    public SysUserResult selectUserById(Long userId) {
        SysUserResult sysUserResult = baseMapper.selectUserById(userId);
        return sysUserResult;
    }

    /**
     * @param userId 用户id
     * @param orgId  员工所属组织机构id
     * @return
     */
    @Override
    public List<Long> getUserDataScopeIdList(Long userId, Long orgId) {
        Set<Long> userDataScopeIdSet = CollectionUtil.newHashSet();

        if (ObjectUtil.isAllNotEmpty(userId, orgId)) {

            //获取该用户对应的数据范围集合
            List<Long> userDataScopeIdListForUser = sysUserDataScopeService.getUserDataScopeIdList(userId);

            //获取该用户的角色对应的数据范围集合
            List<Long> userDataScopeIdListForRole = sysUserRoleService.getUserRoleDataScopeIdList(userId, orgId);

            userDataScopeIdSet.addAll(userDataScopeIdListForUser);
            userDataScopeIdSet.addAll(userDataScopeIdListForRole);
        }
        return CollectionUtil.newArrayList(userDataScopeIdSet);
    }


    /**
     * 是否租户管理员
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public Boolean isTenantAdmin(Long userId) {
        List<String> roleCodeList = getRoleCodeListByUserId(userId);
        return roleCodeList.contains(RoleConstant.tenant_admin);
    }

    @Override
    public String getNameByUserId(Long userId) {
        SysUser sysUser = this.getById(userId);
        if (ObjectUtil.isNull(sysUser)) {
            throw new ServiceException(SysUserExceptionEnum.USER_NOT_EXIST);
        }
        return sysUser.getName();
    }

    @Override
    public List<Long> ownRole(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        return sysUserRoleService.getUserRoleIdList(sysUser.getId());
    }

    @Override
    public List<Long> ownData(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        return sysUserDataScopeService.getUserDataScopeIdList(sysUser.getId());
    }


    @Override
    public void resetPwd(Long userId) {
        SysUser sysUser = this.getById(userId);
        SysUserFactory.fillAddCommonUserInfo(sysUser);
        this.updateById(sysUser);
    }

    @Override
    public void updateAvatar(SysUserParam sysUserParam) {
        SysUser sysUser = this.querySysUser(sysUserParam);
        String avatar = sysUserParam.getAvatar();
        sysUser.setAvatar(avatar);
        this.updateById(sysUser);
    }

    @Override
    public void export(SysUserParam sysUserParam) {
        List<SysUser> list = this.list();
        PoiUtil.exportExcelWithStream("GunsUsers.xls", SysUser.class, list);
    }

    @Override
    public List<Dict> selector(SysUserParam sysUserParam) {
        List<Dict> dictList = CollectionUtil.newArrayList();
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotNull(sysUserParam)) {
            //根据姓名模糊查询
            if (ObjectUtil.isNotEmpty(sysUserParam.getName())) {
                queryWrapper.like(SysUser::getName, sysUserParam.getName());
            }
        }
        //查询非删除状态，排除超级管理员
        queryWrapper.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode())
                .ne(SysUser::getAdminType, AdminTypeEnum.SUPER_ADMIN.getCode());
        this.list(queryWrapper).forEach(sysUser -> {
            Dict dict = Dict.create();
            dict.put(CommonConstant.ID, sysUser.getId());
            dict.put(CommonConstant.NAME, sysUser.getName());
            dictList.add(dict);
        });
        return dictList;
    }

    /**
     * 校验参数，检查是否存在相同的账号
     *
     * @author xuyuxiang
     * @date 2020/3/27 16:04
     */
    private void checkParam(Long id, String account, boolean isExcludeSelf) {
        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getAccount, account)
                .ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode());
        if (sysLoginUser.getTenantId() != 1l) {
            queryWrapper.eq(SysUser::getTenantId, sysLoginUser.getTenantId());
        } else {
            queryWrapper.eq(SysUser::getTenantId, 1l);
        }
        //是否排除自己，如果是则查询条件排除自己id
        if (isExcludeSelf) {
            queryWrapper.ne(SysUser::getId, id);
        }
        int countByAccount = this.count(queryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new ServiceException(SysUserExceptionEnum.USER_ACCOUNT_REPEAT);
        }
    }

    /**
     * 获取系统用户
     *
     * @author xuyuxiang
     * @date 2020/3/26 9:54
     */
    private SysUser querySysUser(SysUserParam sysUserParam) {
        SysUser sysUser = this.getById(sysUserParam.getId());
        if (ObjectUtil.isNull(sysUser)) {
            throw new ServiceException(SysUserExceptionEnum.USER_NOT_EXIST);
        }
        return sysUser;
    }


    /**
     * 查看用户详细信息
     *
     * @param userId
     * @return
     */
    @Override
    public ResponseData userDetail(Long userId) {
        SysUserResult sysUserResult = new SysUserResult();
        SysUser sysUser = this.baseMapper.selectById(userId);
        BeanUtil.copyProperties(sysUser, sysUserResult);

        return ResponseData.success(sysUser);
    }

    @Override
    public List<Map> orgUser(Long orgId) {
        List<Map> sysUsers = baseMapper.orgUser(orgId);

        return sysUsers;
    }

    @Override
    public List<Long> getRoleList(Long userId) {
        List<Long> roleList = baseMapper.getRoleList(userId);
        return roleList;
    }

    @Override
    public List<String> getRoleCodeListByUserId(Long userId) {
        List<String> roleCodeList = baseMapper.getRoleCodeListByUserId(userId);
        return roleCodeList;
    }

    @Override
    public String getTenantName(String code) {
        return this.baseMapper.getTenantName(code, LoginContextHolder.me().getSysLoginUser().getTenantId());
    }

    @Override
    public SiteResult getSiteName(Long userId) {
        return this.baseMapper.getSiteName(userId);
    }

    @Override
    public ResponseData updatePassword(SysUserParam sysUserParam) {
        if (StringUtils.isBlank(sysUserParam.getPassword())) {
            throw new CustomException("新密码不能为空");
        }
        SysUser user = this.getById(LoginContextHolder.me().getSysLoginUserId());

        if (!user.getPassword().equals(MD5Ry.md5(sysUserParam.getOldPassword()))) {
            throw new CustomException("旧密码错误,请检查密码是否正确");
        }

        SysUser sysUser = new SysUser();
        sysUser.setId(LoginContextHolder.me().getSysLoginUserId());
        sysUser.setPassword(MD5Ry.md5(sysUserParam.getPassword()));
        this.updateById(sysUser);

        return ResponseData.success();
    }

    @Autowired
    private SysEmpMapper sysEmpMapper;


    /**
     * 更改用户所在部门
     *
     * @param changeOrgVo
     * @return
     */
    @Override
    public ResponseData changeOrg(ChangeOrgVo changeOrgVo) {

        //根据部门id查询部门信息
        SysOrg sysOrg = sysOrgMapper.selectOne(new LambdaUpdateWrapper<SysOrg>()
                .eq(SysOrg::getStatus, CommonStatusEnum.ENABLE.getCode())
                .eq(SysOrg::getId, changeOrgVo.getOrgId()));
        if (sysOrg == null) {
            return ResponseData.error("部门不存在！");
        }

        //根据用户id查询用户信息
        SysUser sysUser = sysUserMapper.selectOne(new LambdaUpdateWrapper<SysUser>()
                .eq(SysUser::getStatus, CommonStatusEnum.ENABLE.getCode())
                .eq(SysUser::getId, changeOrgVo.getUserId()));
        if (sysUser == null) {
            return ResponseData.error("用户不存在！");
        }

        //根据用户id查询是否存在部门关联
        SysEmp sysEmp = sysEmpMapper.selectById(changeOrgVo.getUserId());

        //如果没查到新增
        if (sysEmp == null) {
            sysEmp = new SysEmp();
            sysEmp.setId(changeOrgVo.getUserId());
            sysEmp.setOrgId(changeOrgVo.getOrgId());
            sysEmp.setOrgName(sysOrg.getName());
            sysEmp.setTenantId(LoginContextHolder.me().getTenantId());
            sysEmpMapper.insert(sysEmp);
        } else {
            //修改
            SysEmp updateSysEmp = new SysEmp();
            updateSysEmp.setOrgId(changeOrgVo.getOrgId());
            updateSysEmp.setOrgName(sysOrg.getName());
            updateSysEmp.setId(sysEmp.getId());
            updateSysEmp.setTenantId(LoginContextHolder.me().getTenantId());
            sysEmpMapper.updateById(updateSysEmp);
        }

        //更改数据权限
        List<Long> orgIdList = new ArrayList<>();
        orgIdList.add(changeOrgVo.getOrgId());
        SysUserParam sysUserParam = new SysUserParam();
        sysUserParam.setGrantOrgIdList(orgIdList);
        sysUserParam.setId(sysUser.getId());
        sysUserDataScopeService.grantData(sysUserParam);

        //更改角色
        SysUserParam roleParam = new SysUserParam();
        List<Long> grantRoleIdList = new ArrayList<>();
        grantRoleIdList.add(sysOrg.getRoleId());
        roleParam.setId(sysUser.getId());
        roleParam.setGrantRoleIdList(grantRoleIdList);
        grantRole(roleParam);
        return ResponseData.success();
    }


}
